{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Clustering 聚类\n",
    "\n",
    "## 分解聚类\n",
    "[代码](Machine-Learning-basic/K-means/decomposition_clustering.py)\n",
    "\n",
    "## k-means\n",
    "[code](Machine-Learning-basic/K-means/k-means.py)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "data shape: (150, 4) , lable shape : (150, 1)\n",
      "data mat shape (150, 4)\n",
      " ********\n",
      "finished : max_E :528.4556935226608, last_max_E:528.4556935226608\n",
      "************\n",
      "data mat shape (150, 4)\n",
      " ********\n",
      "finished : max_E :68.14419921461881, last_max_E:68.14419921461878\n",
      "************\n",
      "{'0': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 57, 93, 98], '1': [114, 146, 133, 149, 101, 142, 123, 83, 76, 50, 113, 127, 72, 126, 119, 86, 121, 138, 70, 56, 54, 58, 63, 51, 65, 75, 68, 73, 91, 85, 78, 87, 74, 66, 97, 55, 84, 61, 106, 90, 96, 71, 94, 95, 99, 62, 88, 67, 92, 53, 89, 82, 69, 59, 80, 64, 81, 79, 60], '2': [118, 117, 131, 122, 105, 135, 109, 107, 130, 125, 102, 129, 143, 120, 144, 100, 124, 140, 104, 139, 112, 108, 136, 132, 141, 128, 145, 115, 148, 116, 137, 103, 147, 110, 111, 77, 52, 134]}\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0.9433962264150944, 0.7627118644067796, 0.9473684210526315]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "from copy import deepcopy\n",
    "import matplotlib.pyplot as plt\n",
    "from mpl_toolkits.mplot3d import Axes3D \n",
    "data_no = 1\n",
    "\n",
    "N = 0 # data number\n",
    "D = 0 # data dimesions\n",
    "iris = 'K-means/iris.txt'\n",
    "text_Data = 'text_data.txt'\n",
    "if(data_no == 1):\n",
    "    file_name = iris\n",
    "    N = 150 # data number\n",
    "    D = 4 # data dimesions\n",
    "elif(data_no == 3):\n",
    "    file_name = 'iris2.txt'\n",
    "    N = 100\n",
    "    D = 4\n",
    "else:\n",
    "    file_name = text_Data\n",
    "    N = 21\n",
    "    D = 2\n",
    "raw_data_file = open(file_name,'r')\n",
    "raw_data = raw_data_file.readlines()\n",
    "\n",
    "\n",
    "\n",
    "data_mat = np.zeros((N,D))\n",
    "lable_mat = np.zeros((N,1))\n",
    "arritubutes = []\n",
    "data_len = D + 1 #data dim plus label\n",
    "lable_dic = {'Iris-setosa' :0, 'Iris-versicolor':1, 'Iris-virginica':2}\n",
    "k = 3 # k classes\n",
    "for i, data in enumerate(raw_data):\n",
    "    #print(i)\n",
    "    #print(data)\n",
    "    data_list = data.split(',')\n",
    "    arritubutes = [float(x) for i, x in  enumerate(data_list) if(i < D)]\n",
    "    data_mat[i] = arritubutes\n",
    "    #lable_mat[i] = lable_dic[data_list[-1].strip('\\n')]\n",
    "    #print(data_mat[i])\n",
    "    #data_mat.row_stack(data_list[:data_len-2])\n",
    "    #lable_mat.row_stack(data_list[-1])\n",
    "print(\"data shape: {} , lable shape : {}\".format(data_mat.shape, lable_mat.shape))\n",
    "predict_label = np.zeros(lable_mat.shape,dtype = np.int32)\n",
    "N_list = []\n",
    "#Objective_E = np.array(150)\n",
    "N_list.append(N)\n",
    "N_list.append(0)\n",
    "N_list.append(0)\n",
    "init_data_index = list(range(0,N,1))\n",
    "G_dic = {'0' : init_data_index, '1' : [], '2' :[]}\n",
    "\n",
    "#current_G1_mat = data_mat.copy()\n",
    "#current_G2_mat = np.zeros(data_mat.shape)\n",
    "\n",
    "# x_mean_1 = np.mean(current_G1_mat, axis = 0) # x^(k+1)\n",
    "# x_mean_2 = np.mean(current_G2_mat, axis = 0)\n",
    "# print(x_mean_1)\n",
    "# print(x_mean_2)\n",
    "\n",
    "max_E_index = np.inf\n",
    "max_E_last = 0\n",
    "max_E = 0\n",
    "iter = 0\n",
    "# new idea use a dic{[]}  to store 3 classes' index\n",
    "#[0~149] [] [] , then change this \n",
    "#for k_i in range(k - 1):\n",
    "#print(G_dic[str(0)])\n",
    "#print(len(G_dic[str(0)]))\n",
    "for k in range(2):\n",
    "    iter += 1\n",
    "    max_E_index = np.inf\n",
    "    max_E_last = 0\n",
    "    max_E = 0\n",
    "    print(\"data mat shape {}\".format(data_mat.shape))\n",
    "    #print(x_mean_1)\n",
    "    #print(x_mean_2)\n",
    "\n",
    "    while(1):\n",
    "        current_G1_mat = data_mat[G_dic[str(k)],: ].copy().reshape((len(G_dic[str(k)]), D))\n",
    "        current_G2_mat = data_mat[G_dic[str(k+1)],:].copy()\n",
    "        if(not len(G_dic[str(k+1)]) == 0):\n",
    "            current_G2_mat = current_G2_mat.reshape((len(G_dic[str(k+1)]), D))\n",
    "        else:\n",
    "            current_G2_mat = np.zeros((1,D))\n",
    "        if(iter > 2):\n",
    "            print(current_G1_mat.shape)\n",
    "            print(current_G2_mat)\n",
    "        #print(\"G1 mat:{}\".format(current_G1_mat))\n",
    "        #print(\"G2 mat :{}\".#format(current_G2_mat))\n",
    "        #print(current_G1_mat)\n",
    "        #print( np.mean(current_G1_mat, axis = 0))\n",
    "        x_mean_1 = np.mean(current_G1_mat, axis = 0) # x^(k+1)\n",
    "        x_mean_2 = np.mean(current_G2_mat, axis = 0)\n",
    "        #print(\"x k mean : \")\n",
    "        #print(x_mean_1)\n",
    "        #print(x_mean_2)\n",
    "        #print(\"***********\")\n",
    "        #max_E = len(G_dic[str(k)])*len(G_dic[str(k+1)]) / (len(G_dic[str(k)]) + len(G_dic[str(k+1)]))*((x_mean_1 - x_mean_2).T) * (x_mean_1 - x_mean_2)\n",
    "        #max_E = np.sqrt(np.sum(max_E ** 2))\n",
    "        max_E = len(G_dic[str(k)])*len(G_dic[str(k+1)]) / (len(G_dic[str(k)]) + len(G_dic[str(k+1)]))*np.sum((x_mean_1 - x_mean_2)**2)\n",
    "        #print(\"current E:  {}\".format(max_E))\n",
    "        max_E_index = np.inf\n",
    "        if(iter >2):\n",
    "            print(\"max E init :{}\".format(max_E))\n",
    "        for i, x_index in enumerate(G_dic[str(k)]):\n",
    "            #iter += 1\n",
    "            x_data = data_mat[x_index]\n",
    "            #print(\"x:{} index: {}\".format(x_data,x_index))\n",
    "            G_dic_temp = deepcopy(G_dic)\n",
    "            G_dic_temp[str(k)].remove(x_index)\n",
    "            G_dic_temp[str(k+1)].append(x_index)\n",
    "            # temp_G1_mat = data_mat[G_dic_temp[str(k)], :].copy()\n",
    "            # temp_G2_mat = data_mat[G_dic_temp[str(k+1)] , :].copy()\n",
    "            # temp_G1_mat = temp_G1_mat.reshape((len(G_dic_temp[str(k)]), D))\n",
    "            # temp_G2_mat = temp_G2_mat.reshape((len(G_dic_temp[str(k+1)]), D))\n",
    "            #print(temp_G1_mat)\n",
    "            #print(temp_G2_mat)\n",
    "            #print(temp_G1_mat.shape)\n",
    "            #print(temp_G2_mat)\n",
    "            x_mean_1_temp = x_mean_1 + (x_mean_1 - x_data)/ (len(G_dic[str(k)]) -1)\n",
    "            x_mean_2_temp = x_mean_2 - (x_mean_2 - x_data)/ ( len(G_dic[str(k+1)]) + 1)\n",
    "            #print(x_mean_1_temp)\n",
    "            # if(len(G_dic_temp[str(k+1)]) > 1):\n",
    "                # x_mean_2_temp = x_mean_2 - (x_mean_2 - x_data)/ ( len(G_dic_temp[str(k+1)]) - 1)\n",
    "            # else:\n",
    "                # x_mean_2_temp = x_data\n",
    "            if(iter > 2):\n",
    "                \n",
    "            #print(x_mean_2_temp)\n",
    "                print(\"x mean: \")\n",
    "                print(x_mean_1_temp)\n",
    "                print(x_mean_2_temp)\n",
    "            #current_E = (len(G_dic_temp[str(k)]))*len(G_dic_temp[str(+1)] )/(len(G_dic_temp[str(k)]) + len(G_dic_temp[str(k+1)]) )*(x_mean_1_temp - x_mean_2_temp).T * (x_mean_1_temp - x_mean_2_temp)\n",
    "            #print(current_E)\n",
    "            #current_E = np.sqrt(np.sum(current_E ** 2))\n",
    "            current_E = (len(G_dic_temp[str(k)]))*len(G_dic_temp[str(k+1)] )/(len(G_dic_temp[str(k)]) + len(G_dic_temp[str(k+1)]) ) *np.sum( (x_mean_1_temp - x_mean_2_temp)**2)\n",
    "            if(iter > 2):\n",
    "                print( (len(G_dic_temp[str(k)]), len(G_dic_temp[str(k+1)])))\n",
    "                print((len(G_dic_temp[str(k)]))*len(G_dic_temp[str(k+1)] )/(len(G_dic_temp[str(k)]) + len(G_dic_temp[str(k+1)]) ))\n",
    "                print(np.sum( (x_mean_1_temp - x_mean_2_temp)**2))\n",
    "                print(current_E)\n",
    "            #print(current_E)\n",
    "            if current_E > max_E:\n",
    "                max_E = current_E\n",
    "                max_E_index = x_index\n",
    "                \n",
    "        \n",
    "        if(max_E < max_E_last or max_E_index == np.inf):\n",
    "            print(\" ********\\nfinished : max_E :{}, last_max_E:{}\\n************\".format(max_E, max_E_last))\n",
    "            break;\n",
    "        else:\n",
    "            #print(\"\\n\\ninter: {}, add {}\\n\\n\".format(iter, max_E_index))\n",
    "            max_E_last = max_E\n",
    "            #print(G_dic[str(k)])\n",
    "            G_dic[str(k)].remove(max_E_index)\n",
    "            G_dic[str(k+1)].append(max_E_index)\n",
    "            #print(G_dic[str(k)])\n",
    "            #print(G_dic[str(k+1)])\n",
    "            #sample_mean = np.mean(current_data_mat, axis = 0)\n",
    "            #\n",
    "print(G_dic)\n",
    "\n",
    "\n",
    "for k in G_dic:\n",
    "    for ele in G_dic[k]:    \n",
    "        predict_label[ele] = k\n",
    "    \n",
    "    \n",
    "x_axis = data_mat[:,0]\n",
    "y_axis = data_mat[:,1]\n",
    "z_axis = data_mat[:,2]\n",
    "fig = plt.figure() \n",
    "ax = Axes3D(fig) \n",
    "\n",
    "ax.scatter(x_axis, y_axis, z_axis, c=predict_label.reshape(150))\n",
    "# 设置坐标轴显示以及旋转角度\n",
    "ax.set_xlabel('1') \n",
    "ax.set_ylabel('2')\n",
    "ax.set_zlabel('3')\n",
    "ax.view_init(elev=10,azim=235)\n",
    "plt.show()\n",
    "\n",
    "\n",
    "acc = []\n",
    "for k in G_dic:\n",
    "    correct = 0\n",
    "    for ele in G_dic[k]:\n",
    "        if( (int(k))*50 <= ele and (int(k)+1) * 50 > ele ):\n",
    "            correct += 1\n",
    "    acc.append(correct / len(G_dic[k]))\n",
    "print(acc)\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "data shape: (150, 4) , lable shape : (150, 1)\n",
      "init index:25\n",
      "init index:74\n",
      "init index:123\n",
      "init center:\n",
      " [[-1.02184904 -0.1249576  -1.227541   -1.31297673]\n",
      " [ 0.67450115 -0.35636057  0.30783301  0.13322594]\n",
      " [ 0.55333328 -0.8191665   0.64902723  0.79059079]]\n",
      "interation : 1\t rel error : 0.15858335252595449\n",
      "interation : 2\t rel error : 0.0018241257075859475\n",
      "interation : 3\t rel error : 5.898059818321144e-17\n",
      "0 class:[25, 17, 10, 46, 42, 9, 2, 28, 38, 31, 37, 27, 16, 49, 41, 4, 44, 15, 7, 1, 18, 5, 19, 33, 45, 14, 12, 22, 36, 13, 6, 40, 30, 21, 8, 25, 35, 43, 47, 0, 20, 48, 39, 24, 29, 11, 26, 3, 32, 34, 23]\n",
      " 1 class:[74, 83, 64, 96, 93, 67, 101, 73, 74, 114, 66, 119, 90, 53, 95, 91, 58, 134, 88, 97, 57, 142, 99, 80, 79, 94, 68, 63, 87, 121, 106, 82, 138, 72, 54, 60, 133, 84, 61, 89, 81, 62, 92, 149, 113, 55, 98, 126, 59, 78, 71, 69, 146, 123]\n",
      " 2 class:[123, 112, 105, 147, 104, 129, 75, 56, 110, 137, 115, 136, 77, 86, 135, 51, 118, 117, 109, 148, 120, 76, 108, 102, 85, 103, 127, 144, 145, 70, 122, 140, 124, 139, 131, 130, 116, 50, 132, 125, 52, 111, 107, 65, 141, 128, 143, 100] \n",
      "\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1.0]\n",
      "[1.0, 0.7407407407407407]\n",
      "[1.0, 0.7407407407407407, 0.7708333333333334]\n",
      "result is : \n",
      "[[-1.01472152  0.82334082 -1.30336194 -1.2562629 ]\n",
      " [-0.03679913 -0.87058938  0.34679655  0.27930702]\n",
      " [ 1.123832    0.07751999  0.98903676  1.01245143]]\n",
      "[1.0, 0.7407407407407407, 0.7708333333333334]\n",
      "interation 3 times\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "import random\n",
    "import matplotlib.pyplot as plt\n",
    "from mpl_toolkits.mplot3d import Axes3D \n",
    "def NormalizedStd(data):\n",
    "    data_mean = np.mean(data, axis = 0)\n",
    "    data_std = np.std(data, axis = 0)\n",
    "    return (data - data_mean) / data_std\n",
    "    \n",
    "raw_data_file = open('K-means/iris.txt','r')\n",
    "raw_data = raw_data_file.readlines()\n",
    "N = 150 # data number\n",
    "D = 4 # data dimesions\n",
    "data_mat = np.zeros((N,D))\n",
    "lable_mat = np.zeros((N,1))\n",
    "arritubutes = []\n",
    "data_len = D + 1 #data dim plus label\n",
    "lable_dic = {'Iris-setosa' :0, 'Iris-versicolor':1, 'Iris-virginica':2}\n",
    "k = 3 # k classes\n",
    "for i, data in enumerate(raw_data):\n",
    "    data_list = data.split(',')\n",
    "    \n",
    "    arritubutes = [float(x) for i, x in  enumerate(data_list) if(i < data_len - 1)]\n",
    "    data_mat[i] = arritubutes\n",
    "    lable_mat[i] = lable_dic[data_list[-1].strip('\\n')]\n",
    "    #print(data_mat[i])\n",
    "    #data_mat.row_stack(data_list[:data_len-2])\n",
    "    #lable_mat.row_stack(data_list[-1])\n",
    "print(\"data shape: {} , lable shape : {}\".format(data_mat.shape, lable_mat.shape))\n",
    "data_mat = NormalizedStd(data_mat) \n",
    "# pick k centers\n",
    "init_centers = np.zeros((k,D))\n",
    "init_center_index = []\n",
    "for i, index in enumerate(list(range(25,150,49))):\n",
    "    print(\"init index:%d\"%index)\n",
    "    init_centers[i] = data_mat[index]\n",
    "    init_center_index.append(index)\n",
    "    \n",
    "next_centers = init_centers.copy()\n",
    "\n",
    "last_centers  = init_centers.copy()\n",
    "\n",
    "print(\"init center:\\n {}\".format(init_centers))\n",
    "# k-means part\n",
    "class_mat = np.zeros(lable_mat.shape)\n",
    "\n",
    "predict_label = np.zeros(lable_mat.shape,dtype = np.int32)\n",
    "inter = 0\n",
    "class_dic = {'0' :[init_center_index[0]], '1':[init_center_index[1]], '2':[init_center_index[2]]}\n",
    "while(1):\n",
    "    inter += 1\n",
    "    last_centers = next_centers.copy()\n",
    "    random_chose_index = list(range(data_mat.shape[0]))\n",
    "    random.shuffle(random_chose_index)\n",
    "    #strat interation\n",
    "    for i in random_chose_index:\n",
    "        last_centers_2 = next_centers.copy()\n",
    "        closed_distance = np.inf\n",
    "        closed_cls = np.inf\n",
    "        for j in range(last_centers_2.shape[0]):\n",
    "            now_distance = np.sum((data_mat[i] - last_centers_2[j])**2)\n",
    "            if( now_distance < closed_distance):\n",
    "                closed_distance = now_distance.copy();\n",
    "                closed_cls = j\n",
    "                # 第二次迭代开始，改变类别先从原有类中删除\n",
    "        if(inter > 1):\n",
    "            #print(class_dic)\n",
    "            #print(predict_label)\n",
    "            #print(\"try to remove {} from {}\\n\".format(i,predict_label[i][0]))\n",
    "            class_dic[str(predict_label[i][0])].remove(i)\n",
    "                       \n",
    "        class_dic[str(closed_cls)].append(i)\n",
    "        predict_label[i][0] = closed_cls\n",
    "        #print(class_dic)\n",
    "    # update center\n",
    "    # center_temp = np.zeros((1,4))\n",
    "        for i in range(k):\n",
    "            center_temp = np.zeros((1,4))\n",
    "            for index in (class_dic[str(i)]):\n",
    "                center_temp += data_mat[index]\n",
    "            next_centers[i] = center_temp/ (len(class_dic[str(i)]))\n",
    "    #print(\"next\")\n",
    "    #print(next_centers)\n",
    "    #print(\"last\")\n",
    "    #print(last_centers)\n",
    "    #print(np.mean(last_centers - next_centers))\n",
    "    ref_e = abs(np.mean(last_centers - next_centers))\n",
    "    print(\"interation : {}\\t rel error : {}\".format(inter,ref_e))\n",
    "    if(abs(ref_e) < 1e-5):\n",
    "        print(\"0 class:{}\\n 1 class:{}\\n 2 class:{} \\n\".format(class_dic['0'], class_dic['1'], class_dic['2']))\n",
    "        break\n",
    "\n",
    "\n",
    "def draw_Point_Cloud(Points, Lables, axis = True, **kags):\n",
    "\n",
    "    x_axis = Points[:,0]\n",
    "    y_axis = Points[:,1]\n",
    "    z_axis = Points[:,2]\n",
    "    fig = plt.figure() \n",
    "    ax = Axes3D(fig) \n",
    "\n",
    "    ax.scatter(x_axis, y_axis, z_axis, c = Lables)\n",
    "    # 设置坐标轴显示以及旋转角度\n",
    "    ax.set_xlabel('x') \n",
    "    ax.set_ylabel('y')\n",
    "    ax.set_zlabel('z')\n",
    "    ax.view_init(elev=10,azim=235)\n",
    "    if not axis:\n",
    "        #关闭显示坐标轴\n",
    "        plt.axis('off')\n",
    "    \n",
    "    plt.show()\n",
    "\n",
    "draw_Point_Cloud(data_mat, predict_label.reshape(150), axis = True)\n",
    "acc = []\n",
    "for k in class_dic:\n",
    "    correct = 0\n",
    "    for ele in class_dic[k]:\n",
    "        if( (int(k))*50 <= ele and (int(k)+1) * 50 > ele ):\n",
    "            correct += 1\n",
    "    acc.append(correct / len(class_dic[k]))\n",
    "    print(acc)\n",
    "#print(predict_label.reshape(150))\n",
    "print(\"result is : \\n{}\".format(next_centers))\n",
    "print(acc)\n",
    "print(\"interation {} times\".format(inter))\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
